package com.hexinfo.dmpro.component.comparison.handler.impl;

import cn.hutool.core.date.DateUtil;
import com.hexinfo.dmpro.component.comparison.entity.TableContrastDataManagementEntity;
import com.hexinfo.dmpro.component.comparison.handler.IDataContrastHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Slf4j
@Service
public class DataContrastHandler implements IDataContrastHandler {

    @Resource
    TableContrastDataManagementEntity dataManagement;

    /**
     * @Method dataContrast
     * @Param tableFlag
     * @Param index
     * @Param data
     * @Return void
     * @Description 行数据比对
     * @Author Huang Yanyihe
     * @Date 2023/9/10 21:47
     * @Version V1.0
     */
    @Override
//    @Async("dataContrastAsyncTaskExecutor")
    public void dataContrast(String tableFlag, Long index, String data) {
        try {
            //①任务异常终止时结束比对
            checkTaskNotFail(tableFlag);
            //③比对数据是否一致
            contrast(tableFlag, index, data);
            //④判断当当前比对任务是否全部成功完成
            checkTaskAchieve(tableFlag);
        } catch (Exception e) {
            log.error("[数据对比组件]- 表[{}]明细数据对比异常, 异常信息:{}, 对比任务结束,结束时间:{}", tableFlag, e.getMessage(), DateUtil.now(), e);
            return;
        }
    }

    /**
     * @Method checkTaskNotFail
     * @Param tableFlag
     * @Return void
     * @Description 检查任务是否失败
     * @Author Huang Yanyihe
     * @Date 2023/9/18 13:56
     * @Version V1.0
     */
    private void checkTaskNotFail(String tableFlag) {
        if (dataManagement.contrastIsFail(tableFlag)) {
            throw new RuntimeException("任务失败,后续任务停止比对");
        }
    }

    /**
     * @Method contrast
     * @Param tableFlag
     * @Param index
     * @Param data
     * @Return void
     * @Description 比对数据是否一致
     * @Author Huang Yanyihe
     * @Date 2023/9/18 13:57
     * @Version V1.0
     */
    private void contrast(String tableFlag, Long index, String data) {
        if (!dataManagement.getContrastMap().containsKey(tableFlag) || !dataManagement.getContrastMap().get(tableFlag).containsKey(index)) {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                log.error("[数据比对组件]-表[{}]对比数据未到达等到异常:{}", tableFlag, e.getMessage(), e);
            }
            dataContrast(tableFlag, index, data);
        } else {
            //获取比对的一行数据
            String contrastData = dataManagement.getContrastMap().get(tableFlag).get(index);
            if (index.longValue() == 1L) {
                log.info("【数据比对模块】---第一次数据比对开始:" + DateUtil.now());
            }
            //判断数据是否一致,不一致则向查询状态写入错误信息
            if (contrastData != null && data != null && !contrastData.equals(data)) {
                dataManagement.dataContrastError(tableFlag, index, data);
                throw new RuntimeException("数据不一致");
            }
            //比对成功,从比对Map中移除这条数据
            dataManagement.getContrastMap().get(tableFlag).remove(index);
            //调用使用线程锁的自增方法,使比对成功行数加1
            dataManagement.incrSourceContrastNum(tableFlag);
        }
    }

    /**
     * @Method checkTaskAchieve
     * @Param tableFlag
     * @Return void
     * @Description 检查任务是否正确完成
     * @Author Huang Yanyihe
     * @Date 2023/9/18 13:57
     * @Version V1.0
     */
    private void checkTaskAchieve(String tableFlag) {
        //判断当当前比对任务是否全部成功完成
        if (dataManagement.getStatusMap().get(tableFlag).getSourceContrastNum().longValue() == 50000) {
            //修改任务状态为成功即 ACHIEVE
            dataManagement.setAchieveStatus(tableFlag);
            //清空比对表内的数据
            dataManagement.getContrastMap().remove(tableFlag);
            log.info("[数据比对组件] - 表[{}]数据比对结束, 任务开始时间：{}, 任务完成时间：{}, 数据总量:{}", tableFlag,
                    dataManagement.getStatusMap().get(tableFlag).getContrastStartTime(), DateUtil.now()
                    , dataManagement.getStatusMap().get(tableFlag).getTableDataTotal());
        }
    }

}
